-- -------------------------------------------------------------------------
-- Features/Game.lua (Game Features & Utilities)
-- Optimized: Time/Weather Control
-- -------------------------------------------------------------------------

local module = {}

-- [Dependencies]
local ui = nil
local config = nil
local natives = nil
local lang = nil
local debugger = nil
local features_config = nil

-- [Lua 5.4] <const> for function references
local os_clock <const> = os.clock
local pcall <const> = pcall

-- [Lua 5.4] <const> for module name
local MODULE_NAME <const> = "Game"

-- =========================================================================
-- [Configuration Constants]
-- =========================================================================

-- [Lua 5.4] <const> for time control
local TIME_HOUR_MIN <const> = 0
local TIME_HOUR_MAX <const> = 23
local TIME_DEFAULT_HOUR <const> = 12
local TIME_DEFAULT_MINUTE <const> = 0

-- Weather types (GTA V weather names)
local WEATHER_TYPES = {
    "CLEAR", "EXTRASUNNY", "CLOUDS", "OVERCAST", "RAIN", "THUNDER",
    "CLEARING", "NEUTRAL", "SNOW", "BLIZZARD", "SNOWLIGHT",
    "XMAS", "HALLOWEEN"
}

-- [Natives Cache]
local N = {}

-- [Local State]
local state = {
    -- Time control
    freeze_time = false,
    custom_hour = TIME_DEFAULT_HOUR,
    custom_minute = TIME_DEFAULT_MINUTE,

    -- Weather
    weather_idx = 1,
    freeze_weather = false,

    -- Cache
    last_time_set = 0,
    last_weather_set = 0,

    -- Applied values (avoid redundant per-frame native calls)
    applied_pause_clock = nil,
}

-- -------------------------------------------------------------------------
-- Internal Helper Functions
-- -------------------------------------------------------------------------

local function _T(text)
    if _G and _G._T then
        return _G._T(text)
    end
    if lang then
        if lang.get then return lang.get(text) end
        if lang.get_text then return lang.get_text(text) end
    end
    return text
end

local function show_toast(text, type_str)
    if ui and ui.notify then
        ui.notify(text, type_str or "Info")
    elseif util and util.toast then
        util.toast(text)
    end
end

-- -------------------------------------------------------------------------
-- Config Save/Load Helpers
-- -------------------------------------------------------------------------

local function load_config()
    if not features_config then return end
    local saved = features_config.get_module(MODULE_NAME)
    if not saved then return end

    -- Time control
    if saved.freeze_time ~= nil then state.freeze_time = saved.freeze_time end
    if saved.custom_hour ~= nil then state.custom_hour = saved.custom_hour end
    if saved.custom_minute ~= nil then state.custom_minute = saved.custom_minute end

    -- Weather
    if saved.weather_idx ~= nil then state.weather_idx = saved.weather_idx end
    if saved.freeze_weather ~= nil then state.freeze_weather = saved.freeze_weather end
end

local function save_config()
    if not features_config then return end
    features_config.set_module(MODULE_NAME, {
        -- Time control
        freeze_time = state.freeze_time,
        custom_hour = state.custom_hour,
        custom_minute = state.custom_minute,
        -- Weather
        weather_idx = state.weather_idx,
        freeze_weather = state.freeze_weather,
    }, true)
end

-- -------------------------------------------------------------------------
-- Module Interface
-- -------------------------------------------------------------------------

--- Initialize the Game module with required dependencies
-- @param ui_lib table The UI rendering library
-- @param cfg_lib table The configuration management library
-- @param nat_lib table The native functions library
-- @param lang_lib table The language/translation library
-- @param json_lib table The JSON encoding/decoding library
-- @param lexis_lib table The Lexis API library
-- @param debug_lib table The debugger library
-- @return boolean true on success
function module.init(ui_lib, cfg_lib, nat_lib, lang_lib, _, _, debug_lib)
    ui = ui_lib
    config = cfg_lib
    natives = nat_lib
    lang = lang_lib
    debugger = debug_lib

    assert(ui, "[Game] UI library is required")
    assert(config, "[Game] Config library is required")

    -- Load features config
    local ok, fc = pcall(require, "ClickUl.Config.features")
    if ok and fc then features_config = fc end

    if debugger then
        debugger.info("[Game] Module initialized successfully")
    end

    -- Cache native functions
    if natives then
        local function get(name) return natives[name] end

        -- Time natives
        N.NETWORK_OVERRIDE_CLOCK_TIME = get("NETWORK_OVERRIDE_CLOCK_TIME")
        N.PAUSE_CLOCK = get("PAUSE_CLOCK")

        -- Weather natives
        N.SET_WEATHER_TYPE_NOW = get("SET_WEATHER_TYPE_NOW")
        N.SET_WEATHER_TYPE_PERSIST = get("SET_WEATHER_TYPE_PERSIST")
        N.SET_WEATHER_TYPE_NOW_PERSIST = get("SET_WEATHER_TYPE_NOW_PERSIST")
        N.CLEAR_WEATHER_TYPE_PERSIST = get("CLEAR_WEATHER_TYPE_PERSIST")
        N.SET_OVERRIDE_WEATHER = get("SET_OVERRIDE_WEATHER")

        if debugger then debugger.debug("[Game] Natives cached successfully") end
    end

    -- Load saved config
    load_config()

    return true
end

--- Background update loop for Game module
-- Applies time/weather modifications every frame
function module.on_tick()
    if not natives then return end

    local now = os_clock()

    -- 1. Time control
    if state.freeze_time then
        if N.PAUSE_CLOCK and state.applied_pause_clock ~= true then
            pcall(N.PAUSE_CLOCK, true)
            state.applied_pause_clock = true
        end
        if N.NETWORK_OVERRIDE_CLOCK_TIME and now > state.last_time_set then
            pcall(N.NETWORK_OVERRIDE_CLOCK_TIME, state.custom_hour, state.custom_minute, 0)
            state.last_time_set = now + 1.0
        end
    else
        if N.PAUSE_CLOCK and state.applied_pause_clock == true then
            pcall(N.PAUSE_CLOCK, false)
            state.applied_pause_clock = false
        end
    end

    -- 2. Weather control
    if state.freeze_weather and now > state.last_weather_set then
        local weather_name = WEATHER_TYPES[state.weather_idx] or "CLEAR"
        if N.SET_WEATHER_TYPE_NOW_PERSIST then
            pcall(N.SET_WEATHER_TYPE_NOW_PERSIST, weather_name)
        elseif N.SET_WEATHER_TYPE_PERSIST then
            pcall(N.SET_WEATHER_TYPE_PERSIST, weather_name)
        end
        state.last_weather_set = now + 2.0
    end
end

--- Draw the Game module UI
-- Renders Time Control and Weather Control
function module.draw()
    ui.DualColumn(
        function()
            -- Time Control Group
            ui.Group(_T("Time Control"), function()
                state.freeze_time = ui.Checkbox(_T("Freeze Time"), state.freeze_time)

                if state.freeze_time then
                    local new_hour = ui.Slider(_T("Hour"), state.custom_hour, TIME_HOUR_MIN, TIME_HOUR_MAX, 1)
                    if new_hour ~= state.custom_hour then
                        state.custom_hour = new_hour
                        state.last_time_set = 0  -- Force immediate update
                    end

                    local new_minute = ui.Slider(_T("Minute"), state.custom_minute, 0, 59, 1)
                    if new_minute ~= state.custom_minute then
                        state.custom_minute = new_minute
                        state.last_time_set = 0  -- Force immediate update
                    end
                end

                -- Quick time presets
                if ui.Button(_T("Morning (06:00)")) then
                    state.custom_hour = 6
                    state.custom_minute = 0
                    state.freeze_time = true
                    state.last_time_set = 0
                    show_toast(_T("Time set to Morning"), "Success")
                end

                if ui.Button(_T("Noon (12:00)")) then
                    state.custom_hour = 12
                    state.custom_minute = 0
                    state.freeze_time = true
                    state.last_time_set = 0
                    show_toast(_T("Time set to Noon"), "Success")
                end

                if ui.Button(_T("Evening (18:00)")) then
                    state.custom_hour = 18
                    state.custom_minute = 0
                    state.freeze_time = true
                    state.last_time_set = 0
                    show_toast(_T("Time set to Evening"), "Success")
                end

                if ui.Button(_T("Midnight (00:00)")) then
                    state.custom_hour = 0
                    state.custom_minute = 0
                    state.freeze_time = true
                    state.last_time_set = 0
                    show_toast(_T("Time set to Midnight"), "Success")
                end
            end)
        end,
        function()
            -- Weather Control Group
            ui.Group(_T("Weather Control"), function()
                state.freeze_weather = ui.Checkbox(_T("Freeze Weather"), state.freeze_weather)

                if state.freeze_weather then
                    local new_idx = ui.Combo(_T("Weather Type"), state.weather_idx, WEATHER_TYPES)
                    if new_idx ~= state.weather_idx then
                        state.weather_idx = new_idx
                        state.last_weather_set = 0  -- Force immediate update
                    end
                end

                -- Quick weather presets
                if ui.Button(_T("Clear Weather")) then
                    state.weather_idx = 1  -- CLEAR
                    state.freeze_weather = true
                    state.last_weather_set = 0
                    show_toast(_T("Weather set to Clear"), "Success")
                end

                if ui.Button(_T("Rain")) then
                    state.weather_idx = 5  -- RAIN
                    state.freeze_weather = true
                    state.last_weather_set = 0
                    show_toast(_T("Weather set to Rain"), "Success")
                end

                if ui.Button(_T("Thunder")) then
                    state.weather_idx = 6  -- THUNDER
                    state.freeze_weather = true
                    state.last_weather_set = 0
                    show_toast(_T("Weather set to Thunder"), "Success")
                end

                if ui.Button(_T("Snow")) then
                    state.weather_idx = 9  -- SNOW
                    state.freeze_weather = true
                    state.last_weather_set = 0
                    show_toast(_T("Weather set to Snow"), "Success")
                end
            end)
        end
    )
end

function module.on_menu_close()
    save_config()
end

return module
